package network

import (
	"net"
	"strconv"
	"sync"
)

type TcpServer struct {
	connCB     ConnectionCallBack
	exitNofity chan struct{}
	wg         sync.WaitGroup // 在退出时 让tcpServer启动的协程都被回收
}

func NewTcpServer(connCB ConnectionCallBack) *TcpServer {
	return &TcpServer{
		connCB:     connCB,
		exitNofity: make(chan struct{}),
	}
}

func (self *TcpServer) Start(ip string, port int) {
	lister, err := net.Listen("tcp", ip+":"+strconv.Itoa(port))
	if err != nil {
		return
	}
	self.wg.Add(1)
	defer self.wg.Done()
	go func() {
		for {
			select {
			case <-self.exitNofity:
				return
			default:
			}
			conn, err := lister.Accept()
			if err != nil {
				return
			}
			self.wg.Add(1)
			go func() {  // 避免阻塞accept 所有采用go
				NewConnection(conn, self.connCB, self.exitNofity).Work(&self.wg)
				self.wg.Done()
			}()
		}
	}()
}

func (self *TcpServer) Stop() {
	close(self.exitNofity)
	self.wg.Wait()
}
